package net.ufrog.common.converters;

import net.ufrog.common.Logger;
import net.ufrog.common.exception.ServiceException;

import java.util.HashMap;
import java.util.Map;

/**
 * @author ultrafrog, ufrog.net@gmail.com
 * @version 0.1, 2017-07-04
 * @since 0.1
 */
public abstract class Converter<T> {

    private static Map<Class<?>, Converter> mConverter;

    static {
        register();
    }

    /**
     * 转换对象
     *
     * @param obj 待转换对象
     * @param defaultValue 默认值
     * @return 目标对象
     */
    public abstract T convert(Object obj, Object defaultValue);

    /**
     * 读取转换类型
     *
     * @return 转换类型
     */
    public abstract Class<T> getType();

    /**
     * 转换对象
     *
     * @param obj 待转换对象
     * @param defaultValue 默认值
     * @param requestType 请求类型
     * @param <T> 请求范型
     * @return 目标对象
     */
    public static <T> T convert(Object obj, Object defaultValue, Class<T> requestType) {
        Converter converter = mConverter.getOrDefault(requestType, null);
        if (converter != null) {
            return requestType.cast(converter.convert(obj, defaultValue));
        }
        throw new ServiceException("not support type: " + requestType.getName() + ".");
    }

    /**
     * 注册转换器
     *
     * @param converter 转换器
     * @param <T> 类型范型
     */
    public static <T> void register(Converter<T> converter) {
        if (mConverter == null) mConverter = new HashMap<>();
        Logger.info("register converter %s to type %s.", converter.getClass().getName(), converter.getType().getName());
        mConverter.put(converter.getType(), converter);
    }

    /** 转换器注册 */
    private static void register() {
        register(new StringConverter());
        register(new IntegerConverter());
        register(new LongConverter());
        register(new BigDecimalConverter());
        register(new PropertiesConverter());
        register(new BooleanConverter());
    }
}
